package middleware

import (
	"bytes"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"io"
)

// LogMiddlewareBuilder 用于设置各种参数，提供良好的扩展性
// 目前我们就让用户只需要指定 logger 就可以
type LogMiddlewareBuilder struct {
	logger *zap.Logger
	input  bool
}

func NewLogMiddlewareBuilder(logger *zap.Logger) *LogMiddlewareBuilder {
	return &LogMiddlewareBuilder{
		logger: logger,
	}
}

// LogInput 是否打印输入的数据
func (l *LogMiddlewareBuilder) LogInput() *LogMiddlewareBuilder {
	l.input = true
	return l
}

func (l *LogMiddlewareBuilder) Build() gin.HandlerFunc {
	return func(context *gin.Context) {
		// 这里就是各种请求的数据

		// 截断，防止有一些恶意攻击者搞出奇长无比的 URL 打爆日志
		// 你可以把 1024 做成可配置的
		url := context.Request.URL.String()
		if len(url) > 1024 {
			url = url[:1024]
		}
		log := accessLog{
			Url: url,
		}

		if l.input {
			input, _ := io.ReadAll(context.Request.Body)
			context.Request.Body = io.NopCloser(bytes.NewBuffer(input))
			log.Input = string(input)
		}
		defer func() {
			log.MatchRoute = context.FullPath()
			log.Method = context.Request.Method
			l.logger.Info("收到请求：", zap.Any("req", log))
		}()

		context.Next()
	}
}

// 一个请求要记录的信息
type accessLog struct {
	Url    string
	Input  string
	Method string
	// 匹配上的路由
	MatchRoute string
}
